//
//  HGSQuery.m
//
//  Copyright (c) 2008 Google Inc. All rights reserved.
//
//  Redistribution and use in source and binary forms, with or without
//  modification, are permitted provided that the following conditions are
//  met:
//
//    * Redistributions of source code must retain the above copyright
//  notice, this list of conditions and the following disclaimer.
//    * Redistributions in binary form must reproduce the above
//  copyright notice, this list of conditions and the following disclaimer
//  in the documentation and/or other materials provided with the
//  distribution.
//    * Neither the name of Google Inc. nor the names of its
//  contributors may be used to endorse or promote products derived from
//  this software without specific prior written permission.
//
//  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
//  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
//  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
//  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
//  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
//  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
//  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
//  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
//  THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
//  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
//  OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//

#import "HGSQuery.h"
#import "HGSTokenizer.h"

@implementation HGSQuery

@synthesize tokenizedQueryString = tokenizedQueryString_;
@synthesize pivotObjects = pivotObjects_;
@synthesize actionArgument = actionArgument_;
@synthesize flags = flags_;
@synthesize actionOperation = actionOperation_;

- (id)initWithTokenizedString:(HGSTokenizedString *)query 
               actionArgument:(HGSActionArgument *)actionArgument
              actionOperation:(HGSActionOperation *)actionOperation
                 pivotObjects:(HGSResultArray *)pivotObjects
                   queryFlags:(HGSQueryFlags)flags {
  if ((self = [super init])) {
    pivotObjects_ = [pivotObjects retain];
    flags_ = flags;
    actionArgument_ = [actionArgument retain];
    actionOperation_ = [actionOperation retain];
    
    // If we got nil for a query, but had a pivot, turn it into an empty query.
    if (!query && pivotObjects) {
      query = [HGSTokenizer tokenizeString:@""];
    }
    tokenizedQueryString_ = [query retain];
    if (!tokenizedQueryString_) {
      [self release];
      self = nil;
    }
  }
  return self;
}

- (id)initWithString:(NSString *)query
      actionArgument:(HGSActionArgument *)actionArgument
     actionOperation:(HGSActionOperation *)actionOperation
       pivotObjects:(HGSResultArray *)pivotObjects
          queryFlags:(HGSQueryFlags)flags {
  HGSTokenizedString *tokenizedQuery = [HGSTokenizer tokenizeString:query];
  return [self initWithTokenizedString:tokenizedQuery 
                        actionArgument:actionArgument
                       actionOperation:actionOperation
                          pivotObjects:pivotObjects 
                            queryFlags:flags];
}

- (void)dealloc {
  [actionArgument_ release];
  [actionOperation_ release];
  [tokenizedQueryString_ release];
  [pivotObjects_ release];
  [super dealloc];
}

- (HGSResultArray *)pivotObjects {
  HGSResultArray *pivotObjects = nil;
  @synchronized(self) {
    pivotObjects = pivotObjects_;
    // make sure it ends up in any local pool so the caller is safe threading wise
    [[pivotObjects retain] autorelease];
  }
  return pivotObjects;
}

- (HGSResult *)pivotObject {
  HGSResultArray *pivotObjects = [self pivotObjects];
  HGSResult *result = nil;
  if ([pivotObjects count] == 1) {
    result = [pivotObjects objectAtIndex:0];
  }
  return result;
}

- (NSString*)description {
  return [NSString stringWithFormat:@"[%@ - Q='%@' POs=%@ P=<%@>]",
          [self class], [tokenizedQueryString_ originalString],
          pivotObjects_, parent_];
}

@end
